package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.distributor.dto.OrderDeleteBatchDTO;
import com.xbongbong.distributor.vo.OrderDeleteBatchVO;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataValidateProductHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.CreditCardBillInfoPojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.pojo.dto.AddBatchDTO;
import com.xbongbong.paas.pojo.dto.CreditCardBillDTO;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.CellValuePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.AfterSaveVO;
import com.xbongbong.paas.pojo.vo.FormDataGetVO;
import com.xbongbong.paas.service.CouponService;
import com.xbongbong.paas.service.CustomerRuleService;
import com.xbongbong.paas.service.DepartmentService;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.service.TransferBackRuleScriptService;
import com.xbongbong.paas.service.WriteOffRecordService;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.team.TeamDataHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.businessdata.pojo.dto.OrderReviewDTO;
import com.xbongbong.pro.businessproduct.pojo.dto.BusinessProductListDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageLogListDTO;
import com.xbongbong.pro.businesstage.pojo.vo.StageLogListVO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.contractperformance.pojo.ContractPerformanceLogPojo;
import com.xbongbong.pro.contractperformance.pojo.dto.ContractPerformanceDeleteBatchDTO;
import com.xbongbong.pro.contractproduct.pojo.dto.ContractProductDeleteBatchDTO;
import com.xbongbong.pro.contractsurcharge.pojo.dto.ContractSurchargeDeteleBatchDTO;
import com.xbongbong.pro.contractuser.pojo.dto.ContractUserDeleteBatchDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerDynamicAddDTO;
import com.xbongbong.pro.detailtab.dto.ChangeDocumentStatusSaveDTO;
import com.xbongbong.pro.detailtab.vo.ChangeDocumentStatusSaveVO;
import com.xbongbong.pro.detailtab.vo.ProductSummaryVO;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ContractErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.PaymentErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ImportErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.MarketingErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.log.pojo.DetailLogComplexPojo;
import com.xbongbong.pro.message.constant.DistributorOrderPushConstant;
import com.xbongbong.pro.message.constant.OrderPushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.DistributorMessageRabbitMqDTO;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentDeleteBatchDTO;
import com.xbongbong.pro.pushnotify.dto.PushNotifyDeleteDTO;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartQueryHelp;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.analytical.impl.ContractValidateAnalyticalServiceImpl;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.TabConstant;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.InvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.ContractSubDataExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.CreditCardBillTypeEnum;
import com.xbongbong.saas.enums.DistributorAddressEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperatePageEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.RuleSettingEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.DistributorEnum;
import com.xbongbong.saas.enums.business.InvoiceDistributorEnum;
import com.xbongbong.saas.enums.business.OrderEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetDistributorEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.WaitOutStockStatusEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.enums.dictionary.EnableButtonEnum;
import com.xbongbong.saas.enums.dictionary.OrderExpressStatusEnum;
import com.xbongbong.saas.enums.dictionary.OrderPayMentStatusEnum;
import com.xbongbong.saas.enums.dictionary.OrderStatusEnum;
import com.xbongbong.saas.enums.dictionary.OrderTypeEnum;
import com.xbongbong.saas.enums.dictionary.PaymentStatusEnum;
import com.xbongbong.saas.enums.dictionary.ShipStatusEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.help.ExplainHelp;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.help.ProDetailHandlerHelp;
import com.xbongbong.saas.help.SaasCreditHelper;
import com.xbongbong.saas.help.SaasDataInitHelp;
import com.xbongbong.saas.help.SaasDeleteHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.InvoiceRelationshipModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.service.ContractPerformanceService;
import com.xbongbong.saas.service.ContractProductService;
import com.xbongbong.saas.service.ContractSurchargeService;
import com.xbongbong.saas.service.ContractUserService;
import com.xbongbong.saas.service.CreditCardBillService;
import com.xbongbong.saas.service.CustomerCommunicateService;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.saas.service.MobileDetailService;
import com.xbongbong.saas.service.OrderService;
import com.xbongbong.saas.service.PaymentService;
import com.xbongbong.saas.service.PaymentSheetService;
import com.xbongbong.saas.service.PushNotifyService;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.PriceProductSetEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Service("orderService")
public class OrderServiceImpl implements OrderService {

    private static final Logger LOG = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Resource
    private ProductModel productModel;
    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private FormDataValidateProductHelp formDataValidateProductHelp;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private PaymentSheetService paymentSheetService;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private ContractServiceImpl contractService;
    @Resource
    private UserModel userModel;
    @Resource
    private CustomerRuleService customerRuleService;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private UserTeamService userTeamService;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private PaasFormService paasFormService;
    @Resource
    private ContractModel contractModel;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private ContractPerformanceService contractPerformanceService;
    @Resource
    @Lazy
    private CustomerCommunicateService customerCommunicateService;
    @Resource
    private OrderService orderService;
    @Resource
    private MobileDetailService mobileDetailService;
    @Resource
    private ProDetailHandlerHelp proDetailHandlerHelp;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private CouponService couponService;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private AttrDecimalPrecisionHelper attrDecimalPrecisionHelper;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private WriteOffRecordService writeOffRecordService;
    @Resource
    private ChartQueryHelp chartQueryHelp;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private InvoiceRelationshipModel invoiceRelationshipModel;
    @Resource
    private ContractUserService contractUserService;
    @Resource
    private PaymentService paymentService;
    @Resource
    private CreditCardBillService creditCardBillService;
    @Resource
    private ContractProductService contractProductService;
    @Resource
    private ContractSurchargeService contractSurchargeService;
    @Resource
    private PushNotifyService pushNotifyService;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private LogHelp logHelp;
    @Resource
    private FundSetService fundSetService;
    @Resource
    private ContractValidateAnalyticalServiceImpl contractAnalyticalService;
    @Resource
    private SaasCreditHelper saasCreditHelper;
    @Resource
    private TeamDataHelp teamDataHelp;
    @Resource
    private TransferBackRuleScriptService transferBackRuleScriptService;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;

    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {

        JSONObject data = validateDataDTO.getData();
        Long contractId = validateDataDTO.getDataId();
        String corpid = validateDataDTO.getCorpid();
        Long formId = validateDataDTO.getFormId();
        String platform = validateDataDTO.getPlatform();
        Integer distributorMark = validateDataDTO.getDistributorMark();
        Map<String, FieldAttrEntity> explainMap = validateDataDTO.getExplainMap();
        saasSaveHelp.formatLinkBusiness4Save(data, OrderEnum.LINK_DISTRIBUTOR.getAttr(), OrderEnum.LINK_CUSTOMER_HIDE.getAttr(), OrderEnum.LINK_DISTRIBUTOR.getFieldType());
        saasSaveHelp.formatLinkBusiness4Save(data, OrderEnum.LINK_PARTNER_RECEIVER.getAttr(), OrderEnum.LINK_PARTNER_RECEIVER_HIDE.getAttr(), OrderEnum.LINK_PARTNER_RECEIVER.getFieldType());
        boolean isNew = (contractId == null || Objects.equals(contractId, 0L));
        Double amount = FastJsonHelper.getDoubleOrDefaultFromFormData(data, OrderEnum.AMOUNT.getAttr(), 0D);
        Double paymentTotalAmount = 0.0D;
        // 无签订人导入
        if (Objects.equals(validateDataDTO.getNoSignImport(), 1)) {
            saasSaveHelp.formatLinkBusiness4Save(data, OrderEnum.SIGN_PERSON.getAttr(), OrderEnum.SIGN_NAME.getAttr(), FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
        }
        //	编辑情况下根据产品数量变化，更改合同状态
        JSONArray productList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, OrderEnum.PRODUCT.getAttr(), new JSONArray());
        SaasNeedRedundantAttrPojo pojo = new SaasNeedRedundantAttrPojo();

        // 新建合同的时候如果没有关联产品则置为已出库
        boolean allOutBound;
        Boolean productCanSee = true;
        if (isNew) {
            allOutBound = contractAnalyticalService.validateProductDemo(productList, corpid, isNew,contractId, validateDataDTO.getFormId(), data.getLong(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
            //新建时 状态等默认值处理
            for (Map.Entry<String, Object> entry : SaasDataInitHelp.initOrder(amount, validateDataDTO.getLoginUserName()).entrySet()) {
                SaasDataInitHelp.antDataSet(data,entry.getKey(),entry.getValue());
            }
        } else {
            productCanSee = formDataValidateProductHelp.attrCanSee(explainMap.get(OrderEnum.PRODUCT.getAttr()),contractId,validateDataDTO.getCreatorId(),validateDataDTO.getLoginUser(),corpid, XbbRefTypeEnum.CONTRACT.getCode());
            if (productCanSee) {
                // 关联产品字段启用，可见，及高级可见时才校验关联产品
                allOutBound = contractAnalyticalService.validateProductDemo(productList, corpid, isNew,contractId, validateDataDTO.getFormId(), data.getLong(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
            } else {
                // 不可见就取是否出库完毕原值
                Integer outBound = FastJsonHelper.getIntegerOrDefaultFromFormData(data, OrderEnum.ALL_OUT_BOUND.getAttr(), BasicConstant.ONE);
                allOutBound = outBound != 0;
            }
            //编辑和新建和编辑进审批时完全分开
            PaasFormDataEntity paasFormDataEntity = validateDataDTO.getPaasFormDataEntity();
            //编辑进审批时，已经走过一遍beforesave了，无需在设置发货状态值
            if (Objects.nonNull(paasFormDataEntity)) {
                JSONObject oldData = paasFormDataEntity.getData();
                String shipStatus = FastJsonHelper.getStringOrDefaultFromFormData(oldData, OrderEnum.SHIP_STATUS.getAttr(),ShipStatusEnum.UNSHIPPED.getCode());
                if (!Objects.equals(shipStatus,ShipStatusEnum.CLOSED.getCode())) {
                    if (productList.isEmpty()) {
                        data.put(OrderEnum.SHIP_STATUS.getAttr(),ShipStatusEnum.UNSHIPPED.getCode());
                    } else if (allOutBound){
                        data.put(OrderEnum.SHIP_STATUS.getAttr(),ShipStatusEnum.SHIPPED.getCode());
                    } else if (Objects.equals(shipStatus,ShipStatusEnum.SHIPPED.getCode())) {
                        data.put(OrderEnum.SHIP_STATUS.getAttr(),ShipStatusEnum.DELIVERED.getCode());
                    } else if (!Objects.equals(shipStatus,ShipStatusEnum.DELIVERED.getCode())){
                        data.put(OrderEnum.SHIP_STATUS.getAttr(),ShipStatusEnum.UNSHIPPED.getCode());
                    }
                }
            }
        }
        // 新建编辑价目表价格校验
        validateProductPrice(productList, corpid, validateDataDTO.getFormId(), data.getLong(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
        data.put(OrderEnum.ALL_OUT_BOUND.getAttr(), allOutBound ? 1 : 0);
        // 是否开启缺货待生产显示
        if (isNew){
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.CONTRACT_NEW_SHOW_PRODUCE.getAlias(), corpid);
            data.put(OrderEnum.SHOW_PRODUCE.getAttr(), companyConfigEntity != null && companyConfigEntity.getConfigValue().equals(StringConstant.POSITIVE_NUMBER) ? 1 : 0);
        }
        // 合同状态不能主动修改成预签约
        // 合同状态是否需要统计
        String contractStatus = FastJsonHelper.getStringFromFormData(data, OrderEnum.STATUS.getAttr());
        data.put(OrderEnum.IF_STATISTIC.getAttr(),!Objects.equals(contractStatus, OrderStatusEnum.ABOLISHED.getCode()) ? 1 : 0);
        // 需要校验一下合同开票金额是否大于合同金额，如果是这种情况就需要给出提示
        double invoiceAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(data, OrderEnum.INVOICE_AMOUNT.getAttr(), 0d);
        if (invoiceAmount > amount) {
            throw new XbbException(ContractErrorCodeEnum.API_ERROR_203020);
        }
        //只要是当前模式是非自建模式，其它模式下合同中带有回款计划的话，都需要把回款计划移除掉
        Long nowModelType = fundSetService.getModelType(corpid,XbbRefTypeEnum.CRM);
        if (!Objects.equals(nowModelType, ModelTypeEnum.PLAN.getCode())) {
            data.remove(ContractEnum.ADD_PAYMENT.getAttr());
        }
        boolean fromApproval = Objects.nonNull(validateDataDTO.getTaskId());
        JSONArray paymentArray = FastJsonHelper.getJsonArrFromFormData(data, OrderEnum.ADD_PAYMENT.getAttr());
        if (paymentArray != null && !paymentArray.isEmpty()) {
            PaasFormEntity paymentFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.PAYMENT.getCode(), corpid, distributorMark, null);
            FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
            BeanUtil.copyProperties(validateDataDTO,formDataAddDTO);
            formDataAddDTO.setAppId(paymentFormEntity.getAppId());
            formDataAddDTO.setMenuId(paymentFormEntity.getMenuId());
            formDataAddDTO.setFormId(paymentFormEntity.getId());
//            formDataAddDTO.setIsNew(isNew);
            JSONObject paymentData = new JSONObject();
            JSONObject customerData = new JSONObject();
            customerData.put(StringConstant.SAAS_LINK_BUSINESS_ID,data.getString(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
            customerData.put(StringConstant.SAAS_LINK_BUSINESS_NAME,data.getString(OrderEnum.LINK_CUSTOMER_HIDE.getAttr()));
            JSONObject contractData = new JSONObject();
            contractData.put(StringConstant.SAAS_LINK_BUSINESS_ID,contractId == null ? "0" : contractId);
            contractData.put(StringConstant.SAAS_LINK_BUSINESS_NAME, validateDataDTO.getSerialNo());
            paymentData.put(PaymentEnum.CUSTOMER.getAttr(), Collections.singletonList(customerData));
            paymentData.put(PaymentEnum.CONTRACT.getAttr(),Collections.singletonList(contractData));
            paymentData.put(PaymentEnum.ADD_PAYMENT.getAttr(),paymentArray);
            formDataAddDTO.setDataList(paymentData);
            formDataAddDTO.getSaasNeedRedundantAttrPoJo().setParentBusinessType(validateDataDTO.getBusinessType());
            formDataAddDTO.getSaasNeedRedundantAttrPoJo().setParentAmount(data.getDouble(OrderEnum.AMOUNT.getAttr()));
            formDataAddDTO.getSaasNeedRedundantAttrPoJo().setLinkItemFormId(validateDataDTO.getFormId());
            formDataAddDTO.setIsTotalPaymentSheetAmount(false);
            formDataAddDTO.setBusinessType(XbbRefTypeEnum.PAYMENT.getCode());
            AddBatchDTO addBatchDTO = paymentService.beforeSaveBatch(formDataAddDTO, fromApproval);
            paymentTotalAmount = Arith.add(paymentTotalAmount, addBatchDTO.getAmount());
            data.put(OrderEnum.ADD_PAYMENT.getAttr(), paymentArray);
            pojo.setAddBatchDTO(addBatchDTO);
        }
        /**
         * 新增回款单和核销预收款
         */
        JSONArray paymentSheetArray = FastJsonHelper.getJsonArrFromFormData(data, OrderEnum.ADD_PAYMENT_SHEET.getAttr());
        JSONArray writeOffPrepaymentArray = FastJsonHelper.getJsonArrFromFormData(data, OrderEnum.ADD_WRITE_OFF_PREPAYMENT.getAttr());
        if ( CollectionsUtil.isNotEmpty(paymentSheetArray) || CollectionsUtil.isNotEmpty(writeOffPrepaymentArray) ){
            //由于回款单跟核销预收款的表单是一致的，所以还是用回款单的表单
            PaasFormEntity paymentSheetFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), corpid, distributorMark, null);
            FormDataAddDTO paymentSheetAddDTO = new FormDataAddDTO();
            BeanUtil.copyProperties(validateDataDTO,paymentSheetAddDTO);
            paymentSheetAddDTO.setAppId(paymentSheetFormEntity.getAppId());
            paymentSheetAddDTO.setMenuId(paymentSheetFormEntity.getMenuId());
            paymentSheetAddDTO.setFormId(paymentSheetFormEntity.getId());
            JSONObject paymentSheetData = new JSONObject();
            JSONObject customerData = new JSONObject();
            customerData.put(StringConstant.SAAS_LINK_BUSINESS_ID,data.getString(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
            customerData.put(StringConstant.SAAS_LINK_BUSINESS_NAME,data.getString(OrderEnum.LINK_CUSTOMER_HIDE.getAttr()));
            JSONObject contractData = new JSONObject();
            contractData.put(StringConstant.SAAS_LINK_BUSINESS_ID,contractId == null ? "0" : contractId);
            contractData.put(StringConstant.SAAS_LINK_BUSINESS_NAME, validateDataDTO.getSerialNo());
            paymentSheetData.put(PaymentSheetEnum.CUSTOMER_ID.getAttr(),Collections.singletonList(customerData));
            paymentSheetData.put(PaymentSheetEnum.CONTRACT.getAttr(),Collections.singletonList(contractData));
            if ( CollectionsUtil.isNotEmpty(paymentSheetArray)) {
                paymentSheetData.put("addPaymentSheet",paymentSheetArray);
                paymentSheetAddDTO.setDataList(paymentSheetData);
                paymentSheetAddDTO.getSaasNeedRedundantAttrPoJo().setParentBusinessType(validateDataDTO.getBusinessType());
                paymentSheetAddDTO.getSaasNeedRedundantAttrPoJo().setParentAmount(data.getDouble(OrderEnum.AMOUNT.getAttr()));
                paymentSheetAddDTO.getSaasNeedRedundantAttrPoJo().setLinkItemFormId(validateDataDTO.getFormId());
                paymentSheetAddDTO.setBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                AddBatchDTO addPaymentSheetBatchDTO = paymentSheetService.beforeSaveBatch(paymentSheetAddDTO, PaymentSheetTypeEnum.WRITE_OFF, data.getLongValue(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
                paymentTotalAmount = Arith.add(paymentTotalAmount, addPaymentSheetBatchDTO.getAmount());
                data.put(OrderEnum.ADD_PAYMENT_SHEET.getAttr(), paymentSheetArray);
                pojo.setAddPaymentSheetBatchDTO(addPaymentSheetBatchDTO);
            }
            if (CollectionsUtil.isNotEmpty(writeOffPrepaymentArray)) {
                paymentSheetData.put("addWriteOffPaymentSheet",writeOffPrepaymentArray);
                paymentSheetAddDTO.setDataList(paymentSheetData);
                paymentSheetAddDTO.getSaasNeedRedundantAttrPoJo().setParentBusinessType(validateDataDTO.getBusinessType());
                paymentSheetAddDTO.getSaasNeedRedundantAttrPoJo().setParentAmount(data.getDouble(OrderEnum.AMOUNT.getAttr()));
                paymentSheetAddDTO.getSaasNeedRedundantAttrPoJo().setLinkItemFormId(validateDataDTO.getFormId());
                paymentSheetAddDTO.setBusinessType(XbbRefTypeEnum.WRITE_OFF_PREPAYMENT.getCode());
                AddBatchDTO addWriteOffPrepaymentBatchDTO = paymentSheetService.beforeSaveBatch(paymentSheetAddDTO, PaymentSheetTypeEnum.WRITE_OFF_PREPAYMENT, data.getLongValue(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
                paymentTotalAmount = Arith.add(paymentTotalAmount, addWriteOffPrepaymentBatchDTO.getAmount());
                data.put(OrderEnum.ADD_WRITE_OFF_PREPAYMENT.getAttr(), writeOffPrepaymentArray);
                pojo.setAddWriteOffPrepaymentBatchDTO(addWriteOffPrepaymentBatchDTO);
            }
        }
        if (paymentTotalAmount > amount){
            throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208037);
        }
        if ( !Objects.equals(validateDataDTO.getIsImport(), 1) ) {
            FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(validateDataDTO.getCorpid(), validateDataDTO.getFormId(), FormConfigEnum.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN.getConfig());
            boolean isContractAmountEqualPayment = Objects.equals(FormConfigEnum.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN.getConfigValue(), StringConstant.POSITIVE_NUMBER);
            if ( Objects.nonNull(formConfigEntity) ) {
                if ( Objects.equals(formConfigEntity.getConfigValue(), StringConstant.POSITIVE_NUMBER) ) {
                    isContractAmountEqualPayment = true;
                } else {
                    isContractAmountEqualPayment = false;
                }
            }
            if ( isContractAmountEqualPayment ) {
                if ( !Objects.equals(paymentTotalAmount, amount) ) {
                    throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208003);
                }
            }
        }
        validateDataDTO.setSaasNeedRedundantAttrPoJo(pojo);
        // 各种利润信息在前面先算
        contractAnalyticalService.calculateContractCost(validateDataDTO);
//        }

        for (Map.Entry<String,Object> entry : SaasDataInitHelp.initContract().entrySet()){
            SaasDataInitHelp.antDataSet(data,entry.getKey(),entry.getValue());
        }
        Map<String,Boolean> attrCanSeeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        attrCanSeeMap.put(OrderEnum.PRODUCT.getAttr(),productCanSee);
        validateDataDTO.getSaasNeedRedundantAttrPoJo().setAttrCanSeeMap(attrCanSeeMap);

        //这里还需要处理导入的应收账期，如果isImport为1就是导入，导入默认去获取默认账期
        // if (Objects.equals(validateDataDTO.getIsImport(), 1) ) {
        //     String period = fundSetService.getImportDefaultPeriod(corpid, formId, data);
        //     data.put(OrderEnum.RECEIVABLE_PERIOD.getAttr(),period);
        //     validateDataDTO.setData(data);
        // }else {
        //     //处理应收账期字段,应收账期字段保存成json字符串
        //     JSONObject jsonObject = saasUpdateHelp.getJsonObjectOrDefaultFromFormData(data,OrderEnum.RECEIVABLE_PERIOD.getAttr(),null);
        //     String receivablePeriodStr = Objects.isNull(jsonObject)? null : JSON.toJSONString(jsonObject);
        //     data.put(OrderEnum.RECEIVABLE_PERIOD.getAttr(),receivablePeriodStr);
        //     validateDataDTO.setData(data);
        // }
    }

    private void validateProductPrice(JSONArray productList, String corpid,Long formId, Long refId) throws XbbException {
        if (Objects.isNull(productList) || productList.isEmpty()){
            return ;
        }
        Map<Long, Boolean> multiUnitMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> pageProductIds = new HashSet<>();
        for (Object obj : productList){
            JSONObject json = (JSONObject) obj;
            Long productId = json.getLong(SelectProductEnum.PRODUCT.getAttr());
            pageProductIds.add(productId);
            multiUnitMap.put(productId, Objects.equals(json.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr()), 1));
        }
        Map<Long,String> pageProductMap = formDataValidateProductHelp.productExitContract(productList,corpid,new ArrayList<>(pageProductIds));
        if (Objects.nonNull(refId) && refId > 0) {
            Map<String, PriceProductSetEntity> productSetEntityMap = productModel.getPriceMap(corpid, refId, formId, new ArrayList<>(pageProductIds), multiUnitMap);
            // TODO 校验是否符合价目表上下限
            if (!productSetEntityMap.isEmpty()) {
                for (int i = 0; i < productList.size(); i++) {
                    JSONObject product = productList.getJSONObject(i);
                    Long productId = product.getLong(SelectProductEnum.PRODUCT.getAttr());
                    Double sellingPrice = product.getDouble(SelectProductEnum.SELLING_PRICE.getAttr());
                    if (multiUnitMap.get(productId)) {
                        String unit = product.getString(SelectProductEnum.UNIT.getAttr());
                        String key = productId + SymbolConstant.UNDERLINE + unit;
                        if (productSetEntityMap.containsKey(key)) {
                            PriceProductSetEntity priceProductSetEntity = productSetEntityMap.get(key);
                            if (Objects.nonNull(priceProductSetEntity.getPriceCap()) && sellingPrice > priceProductSetEntity.getPriceCap()) {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(I18nStringConstant.LESS_SELLING_PRICE), pageProductMap.get(productId)));
                            }
                            if (Objects.nonNull(priceProductSetEntity.getPriceFloor()) && sellingPrice < priceProductSetEntity.getPriceFloor()) {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(I18nStringConstant.LESS_SELLING_PRICE), pageProductMap.get(productId)));
                            }
                        }
                    } else {
                        if (productSetEntityMap.containsKey(productId.toString())) {
                            PriceProductSetEntity priceProductSetEntity = productSetEntityMap.get(productId.toString());
                            if (Objects.nonNull(priceProductSetEntity.getPriceCap()) && sellingPrice > priceProductSetEntity.getPriceCap()) {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(I18nStringConstant.LESS_SELLING_PRICE), pageProductMap.get(productId)));
                            }
                            if (Objects.nonNull(priceProductSetEntity.getPriceFloor()) && sellingPrice < priceProductSetEntity.getPriceFloor()) {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(I18nStringConstant.LESS_SELLING_PRICE), pageProductMap.get(productId)));
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        JSONObject newData = saasFormSaveDTO.getNewData();
        JSONObject oldData = saasFormSaveDTO.getOldData();
        Long contractId = newPaasFormDataEntity.getId();
        String corpid = newPaasFormDataEntity.getCorpid();
        Boolean isNew = saasFormSaveDTO.getIsNew();
        Long newCustomerId = FastJsonHelper.getLongFromFormData(newData, OrderEnum.LINK_DISTRIBUTOR.getAttr());

        teamDataHelp.saveUserTeam(saasFormSaveDTO.getSaasNeedRedundantAttrPoJo(), contractId, newPaasFormDataEntity, saasFormSaveDTO.getIsImport(), false);
        Integer taskType = saasFormSaveDTO.getTaskType();

        // 优惠券核销记录保存
        try {
            JSONArray coupon = newData.getJSONArray(OrderEnum.COUPON_ID.getAttr());
            if (CollectionUtils.isNotEmpty(coupon) && isNew) {
                couponService.changeCouponStatus(newPaasFormDataEntity,DistributorMarkEnum.DISTRIBUTOR.getCode());
            }
        } catch (Exception e) {
            LOG.error("合同保存优惠券核销记录", e);
            throw new XbbException(MarketingErrorCodeEnum.API_ERROR_1500014);
        }
        // 以下业务应该是可以异步处理的业务
        Runnable runnable = () -> {
            // 合同关联产品保存
            try {
                JSONArray contractProduct = newData.getJSONArray(OrderEnum.PRODUCT.getAttr());
                if (contractProduct != null) {
                    if (saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(OrderEnum.PRODUCT.getAttr())) {
                        contractService.saveProduct(contractProduct, corpid, newPaasFormDataEntity,isNew,saasFormSaveDTO.getNewPaasFormDataEntity().getFormId(), DistributorMarkEnum.DISTRIBUTOR.getCode(),taskType);
                    }
                }
            } catch (Exception e) {
                LOG.error("合同保存产品数据解析/合同保存产品关联产品", e);
            }
            try {
                // 更新合同业绩分配
                List<ContractPerformanceLogPojo> contractPerformanceLogList = new ArrayList<>();
                contractPerformanceService.changeContractPerformance(newPaasFormDataEntity, contractPerformanceLogList);
                if (CollectionsUtil.isNotEmpty(contractPerformanceLogList)) {
                    OperateTypeEnum operateTypeEnum = isNew ? OperateTypeEnum.NEW : OperateTypeEnum.EDIT;

                    UserVO userVO = saasFormSaveDTO.getLoginUser();
                    OperateModuleTypeEnum operateModuleTypeEnum = OperateModuleTypeEnum.getByAlias(XbbRefTypeEnum.ORDER.getAlias());
                    String opObjectName = I18nMessageUtil.getMessage(XbbRefTypeEnum.CONTRACT_PERFORMANCE.getName());
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_DECISION_TREE_UPDATE), userVO.getName(), XbbRefTypeEnum.ORDER.getName(), newPaasFormDataEntity.getSerialNo(), opObjectName);
                    List<DetailLogComplexPojo> detailArr = logHelp.detailLog4ContractPerformance(contractPerformanceLogList);
                    mongoLogHelp.buildLog4ComplexDetailArr(detailArr, userVO.getCorpid(), userVO.getUserId(), userVO.getName(), operateModuleTypeEnum, operateTypeEnum, contractId.toString(), opObjectName, memo, "");
                }
            } catch (Exception e) {
                LOG.error("保存合同更新合同业绩分配", e);
            }
            try {
                if (Objects.nonNull(newCustomerId) && newCustomerId > 0) {
                    // 更新客户状态和最后联系时间
                    JSONObject jsonObject = new JSONObject();
                    CustomerEntityExt customerEntityExt = customerModel.getByKey(newCustomerId, corpid);
                    //新建合同订单，取其创建时间更新影响客户最后跟进时间
                    Boolean flag = paasFormService.getSingleRuleList(corpid, RuleSettingEnum.NEW_CONTRACT_ORDER_CREATE_TIME.getConfig(), customerEntityExt.getFormId());
                    if (flag) {
                        jsonObject.put(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr(), DateTimeUtil.getInt());
                    }

                    if ( !jsonObject.isEmpty() && jsonObject.size() > 0) {
                        UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(newCustomerId, jsonObject, corpid);
                        customerModel.updateBatch(Collections.singletonList(updateDataEntity), corpid);
                    }
                }
            } catch (Exception e) {
                LOG.error("保存合同更新客户状态和最后联系时间", e);
            }

            try {
                // 去除客户标签
                boolean customerSeniorModel = commonHelp.isCustomerPublicPoolSeniorModel(corpid);
                CustomerEntityExt customerEntity = customerModel.getByKey(newCustomerId, corpid);
                Long customerFormId  = customerEntity != null ? customerEntity.getFormId() : 0L;
                if (customerSeniorModel){
                    transferBackRuleScriptService.deletePublicSeniorTag(corpid,Collections.singletonList(newCustomerId),XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),customerFormId);
                }else {
                    customerRuleService.deletePublicTag(corpid, Collections.singletonList(newCustomerId));
                }
            } catch (Exception e) {
                LOG.error("保存合同去除关联客户标签", e);
            }
            Integer pushType = XbbRefTypeEnum.CONTRACT.getCode();
            if (isNew) {
                //创建信息
                String creatorId = newPaasFormDataEntity.getCreatorId();
                UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                //新建订货单
                String operate = Objects.equals(saasFormSaveDTO.getIsImport(), 1) ? I18nMessageUtil.getMessage(I18nStringConstant.IMPORTED) : I18nMessageUtil.getMessage(I18nStringConstant.ADD);
                String communicateMemo = creatorUser.getName() + operate + I18nMessageUtil.getMessage(CommonConstant.ORDER) + " :" + newPaasFormDataEntity.getSerialNo();
                Integer subType = ProjectLogEnum.ORDER_CREATE.getSubType();
                String log = I18nMessageUtil.getMessage(I18nStringConstant.ORDER_CREATE_LOG);

                // 动态： 经销商，暂不考虑
                // DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategy(subType);
                // dynamicStrategy.save(DynamicSaveDTO.initDynamicSaveDTO(newPaasFormDataEntity.getId(), newPaasFormDataEntity.getFormId(), saasFormSaveDTO, creatorUser, null));
                orderService.projectLog(saasFormSaveDTO, creatorId, newCustomerId, communicateMemo, subType, log);
                String type = newData.getString(OrderEnum.TYPE.getAttr());
                try {
                    if (!Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                        ContractEntityExt contractEntityExt = new ContractEntityExt();
                        BeanUtil.copyProperties(newPaasFormDataEntity, contractEntityExt);
                        // 订货单创建消息推送
                        List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.ORDER_ADD_PUSH.getCode(), PushTypeEnum.ORDER_ADD_PUSH.getSubCode(), creatorUser, contractEntityExt);
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(contractEntityExt.getAppId(), contractEntityExt.getMenuId(), contractEntityExt.getFormId(), contractId, Collections.singletonList(contractId), SaasMarkEnum.SAAS.getCode(), pushType, pushType);
                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(contractId), 0, null, I18nMessageUtil.getMessage(OrderPushConstant.ORDER_ADD_TITLE), String.format(I18nMessageUtil.getMessage(OrderPushConstant.ORDER_ADD_CONTENT), creatorUser.getName(), contractEntityExt.getSerialNo()), null, options);
                        baseProducer.sendMessage(PushTypeEnum.ORDER_ADD_PUSH, messageRabbitMqDTO);
                        // 代客下单消息推送
                        List<String> pushDistributorUserList = pushHelper.getDistributorUserIdListByPushSetRule(corpid, newData.getLongValue(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
                        if (OrderTypeEnum.VALET_ORDER.getCode().equals(type)) {
                            // 订货单消息推送到经销商
                            DistributorMessageRabbitMqDTO distributorMessageRabbitMqDTO = new DistributorMessageRabbitMqDTO(corpid, pushDistributorUserList, Collections.singletonList(contractId), 0, null, I18nMessageUtil.getMessage(DistributorOrderPushConstant.ORDER_ADD_TITLE), String.format(I18nMessageUtil.getMessage(DistributorOrderPushConstant.ORDER_ADD_CONTENT), creatorUser.getName(), contractEntityExt.getSerialNo()), null, options, DistributorMarkEnum.DISTRIBUTOR.getCode());
                            baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_ORDER_ADD_PUSH, distributorMessageRabbitMqDTO);
                        }
                    }
                } catch (Exception e) {
                    LOG.error("订货单创建消息推送", e);
                }
            }

            try {
                if (!Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                    // 订单状态变更消息推送
                    if (!Objects.equals(oldData.getString(OrderEnum.STATUS.getAttr()), newData.getString(OrderEnum.STATUS.getAttr()))) {
                        String oldStatus = dataDictionaryModel.getDictionaryValue(saasFormSaveDTO.getCorpid(), DictionaryEnum.CONTRACT_STATUS, oldData.getInteger(OrderEnum.STATUS.getAttr()));
                        String newStatus = dataDictionaryModel.getDictionaryValue(saasFormSaveDTO.getCorpid(), DictionaryEnum.CONTRACT_STATUS, newData.getInteger(OrderEnum.STATUS.getAttr()));
                        ContractEntityExt contractEntityExt = new ContractEntityExt();
                        BeanUtil.copyProperties(newPaasFormDataEntity, contractEntityExt);
                        List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.ORDER_CHANGE_PUSH.getCode(), PushTypeEnum.ORDER_CHANGE_PUSH.getSubCode(), saasFormSaveDTO.getLoginUser(), contractEntityExt);
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(contractEntityExt.getAppId(), contractEntityExt.getMenuId(), contractEntityExt.getFormId(), contractId, Collections.singletonList(contractId), SaasMarkEnum.SAAS.getCode(), pushType, pushType);
                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(contractId), 0, null, I18nMessageUtil.getMessage(OrderPushConstant.ORDER_CHANGE_TITLE), String.format(I18nMessageUtil.getMessage(OrderPushConstant.ORDER_CHANGE_CONTENT), saasFormSaveDTO.getLoginUserName(), oldStatus, newStatus), null, options);
                        baseProducer.sendMessage(PushTypeEnum.ORDER_CHANGE_PUSH, messageRabbitMqDTO);
                    }
                }
            } catch (Exception e) {
                LOG.error("订货单保存时订单状态变更消息推送", e);
            }
        };
        threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
    }

    /**
     * 项目日志
     *
     * @param saasFormSaveDTO 参数
     * @param creatorId 创建人id
     * @param newCustomerId 客户id
     * @param communicateMemo 备注
     * @param subType 日志类型
     * @param log 日志
     * @author 徐俊杰
     * @date 2019/8/27 14:43
     * @since v1.0
     */
    @Override
    public void projectLog(SaasFormSaveDTO saasFormSaveDTO, String creatorId, Long newCustomerId, String communicateMemo, Integer subType, String log) {
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        JSONObject newData = saasFormSaveDTO.getNewData();
        String corpid = newPaasFormDataEntity.getCorpid();
        Long contractId = newPaasFormDataEntity.getId();
        //拼装
        try {
            CustomerDynamicAddDTO customerDynamicAddDTO = new CustomerDynamicAddDTO();
            String customerName = newData.getString(OrderEnum.LINK_CUSTOMER_HIDE.getAttr());
            customerDynamicAddDTO.setCorpid(corpid);
            customerDynamicAddDTO.setUserId(creatorId);
            customerDynamicAddDTO.setCustomerId(newCustomerId);
            customerDynamicAddDTO.setCustomerName(customerName);
            customerDynamicAddDTO.setMemo(communicateMemo);
            customerDynamicAddDTO.setCommunicateBusinessText(newPaasFormDataEntity.getSerialNo());
            customerDynamicAddDTO.setCommunicateBusinessType(saasFormSaveDTO.getBusinessType());
            customerDynamicAddDTO.setDataId(contractId);
            customerDynamicAddDTO.setLogType(subType);
            customerDynamicAddDTO.setDistributorMark(saasFormSaveDTO.getDistributorMark());
            customerCommunicateService.addCustomerDynamic(customerDynamicAddDTO);
        } catch (Exception e) {
            LOG.error(log, e);
        }
    }

    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(importFormDataDTO, formDataAddDTO);
        formDataAddDTO.setSerialNo("");
        JSONObject dataJson = new JSONObject();
        List<List<CellValuePojo>> rowValueList = rowGroupPojo.getRowValueList();
        // 分组的第一条数据作为给实体对象赋值的数据
        List<CellValuePojo> cellValueList = rowValueList.get(0);

        Long linkCustomerId = 0L;
        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String corpid = importFormDataDTO.getCorpid();
        for (FieldAttrEntityForImport fieldAttr : fieldAttrList) {
            String attr = fieldAttr.getAttr();
            Integer fieldType = fieldAttr.getFieldType();
            String attrName = fieldAttr.getAttrName();
            Integer columnIndex = importHelper.getColumnIndexByTitle(titlePojoList, attrName, null);
            Object cellValue = importHelper.getValueByColumnIndex(cellValueList, columnIndex);
            if (Objects.equals(attr, OrderEnum.PRODUCT.getAttr())) {
                importHelper.formatCommonProduct(titlePojoList, dataJson, rowValueList, fieldAttr, XbbRefTypeEnum.CONTRACT.getCode(), corpid);
            } else if (Objects.equals(attr, OrderEnum.LINK_DISTRIBUTOR.getAttr())) {
                // 关联客户根据linkedType判断
                linkCustomerId = importHelper.formatLinkCustomer2CustomerId(titlePojoList, dataJson, rowValueList, fieldAttr);
            } else if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType())) {
                importHelper.formatSubFormValue4Import(rowValueList, titlePojoList, importFormDataDTO, fieldAttr, dataJson);
            } else if (Objects.equals(attr, OrderEnum.LINK_PARTNER_RECEIVER.getAttr())) {
                // 收货人
                boolean isMatchReceiver = false;
                Map<Long, List<ContractSubDataExt>> addressMap = fieldAttr.getShippingAddressMap();
                if (addressMap != null) {
                    List<ContractSubDataExt> addressList = addressMap.get(linkCustomerId);
                    for (ContractSubDataExt contractSubDataExt : addressList) {
                        JSONObject subDataObj = contractSubDataExt.getData();
                        if (Objects.equals(subDataObj.getString(DistributorAddressEnum.RECEIVER.getAttr()), Objects.toString(cellValue))) {
                            subDataObj.put("id", contractSubDataExt.getId());
                            subDataObj.put("name", Objects.toString(cellValue));
                            subDataObj.put("dataId", contractSubDataExt.getDataId());
                            subDataObj.put("formId", contractSubDataExt.getFormId());
                            JSONArray receiverArray = new JSONArray();
                            receiverArray.add(subDataObj);
                            dataJson.put(attr, receiverArray);
                            dataJson.put(OrderEnum.LINK_CONTACT_NUMBER.getAttr(), subDataObj.getString(DistributorAddressEnum.PHONE.getAttr()));
                            dataJson.put(OrderEnum.SHIPPING_ADDRESS.getAttr(), subDataObj.getJSONObject(DistributorAddressEnum.ADDRESS.getAttr()));
                            isMatchReceiver = true;
                            break;
                        }
                    }
                }
                if (!isMatchReceiver) {
                    throw new XbbException(ImportErrorCodeEnum.API_ERROR_235055);
                }
            } else {
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    continue;
                }
                // 签订人特殊处理
                if (Objects.equals(attr, OrderEnum.SIGN_PERSON.getAttr())) {
                    Map<String, Object> linkBusinessMap = fieldAttr.getLinkBusinessMap();
                    if (linkBusinessMap.containsKey(cellValue.toString())) {
                        returnUserAndDepartmentPojo.setId(linkBusinessMap.get(cellValue.toString()));
                    } else {
                        // 签订人错误数据id用-1
                        if (Objects.equals(importFormDataDTO.getIsNoSignImport(), 1)) {
                            returnUserAndDepartmentPojo.setId(StringConstant.NOT_IN_SYSTEM_ID);
                            returnUserAndDepartmentPojo.setName(cellValue.toString());
                        } else {
                            throw new XbbException(ImportErrorCodeEnum.API_ERROR_235013);
                        }
                    }
                    dataJson.put(attr, JSON.toJSON(returnUserAndDepartmentPojo));
                } else if (ImportHelper.commonHandleFieldType.contains(fieldAttr.getFieldType())) {
                    importHelper.formatCommonField(dataJson, fieldAttr, cellValue);
                } else {
                    if (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())) {
                        formDataAddDTO.setSerialNo(cellValue.toString());
                    } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                        importHelper.formatLinkData(cellValue, fieldAttr, dataJson);
                    } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                        importHelper.formatLinkDataMulti(cellValue, importFormDataDTO, fieldAttr, dataJson);
                    } else {
                        dataJson.put(attr, cellValue);
                    }
                }
            }
            if (Objects.equals(attr, ContractEnum.ADD_PAYMENT.getAttr())) {
                if (Objects.nonNull(fieldAttr.getSubForm()) && Objects.nonNull(fieldAttr.getSubForm().getItems())) {
                    explainMap = ExplainUtil.getExplainMapByList(fieldAttr.getSubForm().getItems());
                }
            }
        }
        JSONArray paymentArr = dataJson.getJSONArray(ContractEnum.ADD_PAYMENT.getAttr());
        List<String> canCoverStatusList = Arrays.asList(PaymentStatusEnum.RECEIVABLES.getCode(), PaymentStatusEnum.UN_RECEIVABLES.getCode());
        if (Objects.nonNull(paymentArr) && !paymentArr.isEmpty()) {
            for (int i = 0; i < paymentArr.size(); i++) {
                JSONObject paymentObj = paymentArr.getJSONObject(i).getJSONObject(StringConstant.JSON_DATA);
                if (!canCoverStatusList.contains(paymentObj.getString(PaymentEnum.STATUS.getAttr()))) {
                    throw new XbbException(ImportErrorCodeEnum.API_ERROR_235019);
                }
                if (Objects.equals(paymentObj.getString(PaymentEnum.STATUS.getAttr()), PaymentStatusEnum.RECEIVABLES.getCode())) {
                    paymentObj.put(PaymentEnum.BELONGER.getAttr(), returnUserAndDepartmentPojo);
                }
                if (Objects.nonNull(paymentObj.get(FieldTypeEnum.DEPARTMENTID.getAlias()))) {
                    Long departmentId = departmentService.verifyDepartment(importFormDataDTO, explainMap, paymentObj);
                    paymentArr.getJSONObject(i).put(FieldTypeEnum.DEPARTMENTID.getAlias(), departmentId);
                    paymentObj.put(FieldTypeEnum.DEPARTMENTID.getAlias(), new ReturnUserAndDepartmentPojo(departmentId));
                }
            }
        }
        dataJson.put(ContractEnum.ADD_PAYMENT.getAttr(), paymentArr);
        formDataAddDTO.setDataList(dataJson);
        return formDataAddDTO;
    }

    @Override
    public ListAppVO formatOrderAppList(FormDataListDTO formDataListDTO, List<PaasFormDataEntityExt> esEntities, Integer totalCount) throws XbbException {
        List<AppListPojo> appListPojos = new ArrayList<>();
        String corpid = formDataListDTO.getCorpid();
        Map<String, FieldAttrEntity> explainMap = formDataListDTO.getExplainMap();

        List<Long> contractIdIn = new ArrayList<>(totalCount);
        contractIdIn.add(-1L);
        for (PaasFormDataEntityExt entity : esEntities) {
            contractIdIn.add(entity.getDataId());
        }

        FieldAttrEntity contactAmountExplain = explainMap.get(ContractEnum.AMOUNT.getAttr());
        boolean amountVisible = false;
        if (contactAmountExplain != null && Objects.equals(contactAmountExplain.getVisible(), 1)) {
            amountVisible = true;
        }
        for (PaasFormDataEntityExt contractEntity : esEntities) {
            JSONObject data = contractEntity.getData();
            Long contractId = contractEntity.getDataId();
            String searNo = contractEntity.getSerialNo() == null ? "" : contractEntity.getSerialNo();
            Long appId = contractEntity.getAppId();
            Long menuId = contractEntity.getMenuId();
            Long formId = contractEntity.getFormId();
            Integer isRed = FastJsonHelper.getIntegerOrDefaultFromFormData(data, ContractEnum.IS_RED.getAttr(), 0);
            String amount = FastJsonHelper.getStringOrDefaultFromFormData(data, ContractEnum.AMOUNT.getAttr(), "0");

            String unit = I18nMessageUtil.getMessage(TabConstant.YUAN);
            amount += unit;
            if (!amountVisible) {
                amount = StringConstant.INVISIBLE_VALUE;
            }

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();


            // 归档标志：1代表归档，2代表未归档
            JSONObject tagData = contractEntity.getTagData();
            if(Objects.equals(tagData.getInteger("isAchived"), 1)){
                superScript.put("archived", 1);
            }
            /*-- 标签 -*/

            /*-- 其他 -*/
            others.put("amount", amount);
            others.put("isRed", isRed);

            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<SummaryDataPoJo> lablesList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            // 进行了退货退款的合同塞一个标签(退货合同)
            //是否包含红冲合同（即是否为退货合同）
            Integer hasRed = FastJsonHelper.getIntegerOrDefaultFromFormData(data, ContractEnum.HAS_RED.getAttr(), 0);
            if (Objects.equals(hasRed, 1)) {
                SummaryDataPoJo dataPoJo = new SummaryDataPoJo();
                String name = I18nMessageUtil.getMessage(I18nStringConstant.RETURN_CONTRACT);
                dataPoJo.setAttr("");
                dataPoJo.setType("red");
                dataPoJo.setAttrName(name);
                dataPoJo.setFieldType(3);
                List<Object> objectList = new ArrayList<>();
                Object obj = name;
                objectList.add(obj);
                dataPoJo.setValue(objectList);
                lablesList.add(0, dataPoJo);
            }
            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);

            appListPojos.add(new AppListPojo(contractId, titleList, summaryList, superScript, lablesList, others, appId, menuId, formId));
        }
        ListAppVO listAppVO = new ListAppVO();
        listAppVO.setList(appListPojos);
        listAppVO.setTotalCount(totalCount);
        return  listAppVO;
    }

    @Override
    public void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        JSONObject linkFormData = handlerExplainInLinkItemDTO.getLinkFormData();
        Long linkDataId = handlerExplainInLinkItemDTO.getLinkDataId();
        String corpid = handlerExplainInLinkItemDTO.getCorpid();
        List<FieldAttrEntity> explainList = handlerExplainInLinkItemDTO.getExplainList();
        FieldAttrEntity linkCustomerField = new FieldAttrEntity();
        FieldAttrEntity linkPartnerReceiverField = new FieldAttrEntity();
        FieldAttrEntity linkContactNumberField = new FieldAttrEntity();
        FieldAttrEntity linkShippingAddressField = new FieldAttrEntity();
        for(FieldAttrEntity fieldAttrEntity :explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.LINK_DISTRIBUTOR.getAttr())) {
                linkCustomerField = fieldAttrEntity;
            } else if (Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.LINK_PARTNER_RECEIVER.getAttr())) {
                linkPartnerReceiverField = fieldAttrEntity;
            } else if (Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.LINK_CONTACT_NUMBER.getAttr())) {
                linkContactNumberField = fieldAttrEntity;
            } else if (Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.SHIPPING_ADDRESS.getAttr())) {
                linkShippingAddressField = fieldAttrEntity;
            }
        }
        JSONArray shipArray = linkFormData.getJSONArray(DistributorEnum.SHIPPING_ADDRESS.getAttr());
        JSONObject shipObj = null;
        if (CollectionsUtil.isNotEmpty(shipArray)) {
            for (int i = 0; i < shipArray.size(); i++) {
                JSONObject obj = shipArray.getJSONObject(i);
                if (Objects.equals(obj.getInteger(DistributorAddressEnum.SET_DEFAULT.getAttr()), 1)) {
                    shipObj = obj;
                    break;
                }
            }

        }
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(handlerExplainInLinkItemDTO.getLinkBusinessType());
        switch (redundantTemplateTypeEnum) {
            case CUSTOMER:
                String customerName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, CustomerManagementEnum.NAME.getAttr(), "");
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, customerName, corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT, XbbRefTypeEnum.PREPAYMENT_BALANCE));
                if (Objects.nonNull(shipObj)) {
                    DefaultAttrPoJo linkContactNumber = linkPartnerReceiverField.getDefaultAttr();
                    linkContactNumber.setUseLinkValue(BasicConstant.ONE);
                    linkContactNumber.setLinkFormValue(shipObj.get(DistributorAddressEnum.PHONE.getAttr()));
                    linkContactNumberField.setDefaultAttr(linkContactNumber);
                    DefaultAttrPoJo linkShippingAddress = linkShippingAddressField.getDefaultAttr();
                    linkShippingAddress.setUseLinkValue(BasicConstant.ONE);
                    linkShippingAddress.setLinkFormValue(shipObj.get(DistributorAddressEnum.ADDRESS.getAttr()));
                    linkShippingAddressField.setDefaultAttr(linkShippingAddress);
                    linkPartnerReceiverField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(shipObj.getLong(BusinessConstant.SUB_DATA_ID), shipObj.getString(DistributorAddressEnum.RECEIVER.getAttr()), corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT, null));
                }
                break;
            default:
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }
    }

    @Override
    public ChangeDocumentStatusSaveVO changeDocumentStatus(ChangeDocumentStatusSaveDTO changeDocumentStatusSaveDTO) throws XbbException{
        ChangeDocumentStatusSaveVO changeDocumentStatusSaveVO = new ChangeDocumentStatusSaveVO();
        try {
            Boolean isOpen = changeDocumentStatusSaveDTO.getIsOpen();
            String corpid = changeDocumentStatusSaveDTO.getCorpid();
            Long contractId = changeDocumentStatusSaveDTO.getDataId();
            Integer businessType = changeDocumentStatusSaveDTO.getBusinessType();
            ContractEntityExt contractEntityExt = contractModel.getByKey(contractId, corpid);
            if (Objects.isNull(contractEntityExt)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            JSONObject contractData = contractEntityExt.getData();
            String oldStatus = contractData.getString(OrderEnum.STATUS.getAttr());
            //如果是关闭订货单
            if (!isOpen) {
                contractData.put(OrderEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.CLOSED.getCode());
                contractData.put(OrderEnum.STATUS.getAttr(), OrderStatusEnum.CLOSED.getCode());
            }
            contractModel.update(contractEntityExt);
            //同步关闭状态到关联产品表
            if (!isOpen) {
                contractProductModel.updateWaitOutStatusById(Collections.singletonList(contractId), corpid, WaitOutStockStatusEnum.UNUSUAL.getCode(),BasicConstant.THREE);
            } else if (isOpen) {
                contractProductModel.updateWaitOutStatusById(Collections.singletonList(contractId), corpid, WaitOutStockStatusEnum.NORMAL.getCode(),WaitOutStockStatusEnum.NORMAL.getCode());
            }
            //跟着合同走
            writeOffRecordService.updateOrderStatus(contractData.getString(OrderEnum.STATUS.getAttr()), contractId, corpid);
            // //添加关闭和开启合同的按钮
            // String shipStatus = FastJsonHelper.getStringOrDefaultFromFormData(contractData, ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.UNSHIPPED.getCode());
            // //如果全部出库，则没有开启关闭按钮
            // if (!Objects.equals(shipStatus, ShipStatusEnum.SHIPPED.getCode())) {
            //     ButtonPojo buttonPojo = new ButtonPojo();
            //     if (!Objects.equals(shipStatus,ShipStatusEnum.CLOSED.getCode())&&changeDocumentStatusSaveDTO.getLoginUser().getPermSet().contains(EnableButtonEnum.ORDER_UNABLE.getPermission())){
            //         buttonPojo.setAttr("contract");
            //         buttonPojo.setValue(OperateTypeEnum.UNABLE.getName());
            //         buttonPojo.setLinkBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
            //         List<ButtonPojo> topRightButton = new ArrayList<>();
            //         topRightButton.add(buttonPojo);
            //         changeDocumentStatusSaveVO.setTopRightButton(topRightButton);
            //     }
            // }
            // 刷新页面saas关联新建工作流
            PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
            BeanUtil.copyProperties(contractEntityExt,paasFormDataEntityExt);
            if (Objects.equals(PlatFormEnum.DINGTALK.getValue(), changeDocumentStatusSaveDTO.getPlatform())) {
                // 设置移动端详情右上角操作
                FormDataGetVO formDataGetVO = new FormDataGetVO();
                mobileDetailService.handelMobileWorkFlow(changeDocumentStatusSaveDTO.getLoginUser(), XbbRefTypeEnum.transferBusinessType4Distributor(businessType,DistributorMarkEnum.DISTRIBUTOR.getCode()), formDataGetVO, paasFormDataEntityExt);
                changeDocumentStatusSaveVO.setTopPermissions(formDataGetVO.getTopPermissions());
            }else {
                List<WorkFlowPojo> workFlowPojoList = new ArrayList<>();
                proDetailHandlerHelp.handelDetailWorkFlow(XbbRefTypeEnum.transferBusinessType4Distributor(businessType,DistributorMarkEnum.DISTRIBUTOR.getCode()), paasFormDataEntityExt, workFlowPojoList, changeDocumentStatusSaveDTO.getLoginUser());
                changeDocumentStatusSaveVO.setWorkFlowPojoList(workFlowPojoList);
            }

            // 信用流水相关
            if (!isOpen) {
                // 判断是否需要释放信用
                boolean checkUseCreditFlag = creditCardBillService.checkOrderCardBill(Arrays.asList(contractId), corpid);
                if (checkUseCreditFlag) {
                    Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(contractData, OrderEnum.LINK_DISTRIBUTOR.getAttr(), 0L);
                    String customerName = FastJsonHelper.getStringOrDefaultFromFormData(contractData, OrderEnum.LINK_CUSTOMER_HIDE.getAttr(), "");
                    // 计算需要释放的剩余额度
                    BigDecimal amount = creditCardBillService.calcCreditRemainLimit(customerId, contractId, corpid);
                    CreditCardBillInfoPojo infoPojo = new CreditCardBillInfoPojo(CreditCardBillTypeEnum.ORDER_CLOSE.getCode(), contractEntityExt.getId(), contractEntityExt.getSerialNo(), amount.doubleValue(), customerId, customerName, CreditCardBillTypeEnum.ORDER_CLOSE.getXbbRefTypeEnum().getCode());
                    infoPojo.setCreatorIsDistributor(BasicConstant.ZERO);
                    CreditCardBillDTO creditCardBillDTO = new CreditCardBillDTO(Arrays.asList(infoPojo));
                    BeanUtil.copyProperties(changeDocumentStatusSaveDTO, creditCardBillDTO);
                    saasCreditHelper.addBatchCreditCardBill(creditCardBillDTO);
                }
            }

            if (!isOpen) {
                Runnable runnable = () -> {
                    //创建信息
                    String creatorId = contractEntityExt.getCreatorId();
                    UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
                    String type = contractData.getString(OrderEnum.TYPE.getAttr());
                    List<String> pushDistributorUserList = new ArrayList<>();
                    try {
                        if (OrderTypeEnum.VALET_ORDER.getCode().equals(type)) {
                            pushDistributorUserList = pushHelper.getDistributorUserIdListByPushSetRule(corpid, contractData.getLongValue(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
                        } else if (OrderTypeEnum.INDEPENDENT_ORDER.getCode().equals(type)) {
                            pushDistributorUserList = Collections.singletonList(contractData.getString(OrderEnum.ORDERER_ID.getAttr()));
                        }
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(contractEntityExt.getAppId(), contractEntityExt.getMenuId(), contractEntityExt.getFormId(), contractId, Collections.singletonList(contractId), SaasMarkEnum.SAAS.getCode(), businessType, businessType);
                        DistributorMessageRabbitMqDTO distributorMessageRabbitMqDTO;
                        distributorMessageRabbitMqDTO = new DistributorMessageRabbitMqDTO(corpid, pushDistributorUserList, Collections.singletonList(contractId), 0, null, I18nMessageUtil.getMessage(DistributorOrderPushConstant.ORDER_CLOSE_TITLE), String.format(I18nMessageUtil.getMessage(DistributorOrderPushConstant.ORDER_CLOSE_CONTENT), contractEntityExt.getSerialNo()), null, options, DistributorMarkEnum.DISTRIBUTOR.getCode());
                        baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_ORDER_CLOSE_PUSH, distributorMessageRabbitMqDTO);
                        orderService.pushMessageChangeStatus(contractEntityExt, oldStatus, OrderStatusEnum.CLOSED.getCode(), corpid, changeDocumentStatusSaveDTO);
                    } catch (Exception e) {
                        LOG.error("订货单关闭消息推送", e);
                    }
                };
                threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
            }
        } catch (Exception e) {
            LOG.error("orderServiceImpl.changeDocumentStatus 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());

        }
        return changeDocumentStatusSaveVO;
    }

    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> entities = formatExplainDTO.getExplainList();
        String corpid = formatExplainDTO.getCorpid();
        for (FieldAttrEntity fieldAttrEntity : entities) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, OrderEnum.PRODUCT.getAttr())) {
                explainHelp.formatSelectProductExplains(fieldAttrEntity, XbbRefTypeEnum.CONTRACT, corpid, OperatePageEnum.NEW.getCode(), false);
                fieldAttrEntity.setSupportScanning(BasicConstant.ONE);
                CompanyConfigEntity priceConfig = companyConfigModel.getByConfigAlias(CompanyConfigEnum.PRICE_MANAGE.getAlias(), corpid);
                if (priceConfig != null && Objects.equals(priceConfig.getConfigValue(), "1")) {
                    SaasParticularAttributePoJo saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                    saasParticularAttributePoJo.setIsOpenPrice(BasicConstant.ONE);
                    fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
                }
            }else if( Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.ADD_PAYMENT.getAttr())){
                if ( !formatExplainDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PAYMENT_VIEW.getAlias()) ) {
                    fieldAttrEntity.setVisible(0);
                }
                if ( !formatExplainDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PAYMENT_ADD.getAlias()) ) {
                    fieldAttrEntity.setEditable(0);
                }
//                fieldAttrEntity.setEditable(0);
            } else if( Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.PRODUCT_TOTAL.getAttr())){
                fieldAttrEntity.setEditable(0);
            } else if ( (Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.ADD_WRITE_OFF_PREPAYMENT.getAttr())
                    || Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.ADD_PAYMENT_SHEET.getAttr())) ) {
                if ( !formatExplainDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PAYMENT_SHEET_VIEW.getAlias()) ) {
                    fieldAttrEntity.setVisible(0);
                }
                if ( !formatExplainDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PAYMENT_SHEET_ADD.getAlias()) ) {
                    fieldAttrEntity.setEditable(0);
                }
            }
        }
    }

    @Override
    public StageLogListVO getAllStageArray(StageLogListDTO stageLogListDTO) throws XbbException {
        Long dataId = stageLogListDTO.getDataId();
        Map<String, String> markMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Integer> scheduleList = new ArrayList<>();
        ContractEntityExt contractEntityExt = contractModel.getByKey(dataId, stageLogListDTO.getCorpid());
        JSONObject data = contractEntityExt.getData();
        // 订单状态
        String orderStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, OrderEnum.STATUS.getAttr(), BasicConstant.ONE.toString());
        // 收款状态
        String receiverPaymentStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, OrderEnum.RECEIVE_PAYMENT_STATUS.getAttr(), BasicConstant.ONE.toString());
        // 出库状态
        String shipStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, OrderEnum.SHIP_STATUS.getAttr(), BasicConstant.ONE.toString());
        // 发货状态
        String expressStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, OrderEnum.EXPRESS_STATUS.getAttr(), BasicConstant.ONE.toString());
        // 订单金额
        Double amount = FastJsonHelper.getDoubleOrDefaultFromFormData(data,OrderEnum.AMOUNT.getAttr(),0D);

        StageLogListVO stageLogListVO = new StageLogListVO();

        if (!Objects.equals(orderStatus,OrderStatusEnum.PENDING_ORDER_REVIEW.getCode()) && !Objects.equals(orderStatus,OrderStatusEnum.ABOLISHED.getCode())){
            if (!Objects.equals(receiverPaymentStatus, OrderPayMentStatusEnum.PENDING_SETTLEMENT.getCode()) || Objects.equals(amount,0D)){
                //订单审核通过 财务审核通过
                scheduleList.add(0,1);
                scheduleList.add(1,1);
                if (!Objects.equals(shipStatus,ShipStatusEnum.UNSHIPPED.getCode()) && !Objects.equals(shipStatus,ShipStatusEnum.CLOSED.getCode())){
                    scheduleList.add(2,1);
                    markMap.put("shipStatus",shipStatus);
                    if (!Objects.equals(expressStatus,OrderExpressStatusEnum.DELIVERED.getCode())){
                        scheduleList.add(3,1);
                        markMap.put("expressStatus",expressStatus);
                        if (Objects.equals(orderStatus,OrderStatusEnum.COMPLETED.getCode())){
                            scheduleList.add(4,1);
                        }else {
                            scheduleList.add(4,0);
                        }
                    }else {
                        scheduleList.add(3,0);
                        scheduleList.add(4,0);
                        markMap.put("expressStatus",BasicConstant.ZERO.toString());
                    }
                }else {
                    scheduleList.add(2,0);
                    scheduleList.add(3,0);
                    scheduleList.add(4,0);
                    markMap.put("shipStatus",BasicConstant.ZERO.toString());
                    markMap.put("expressStatus", BasicConstant.ZERO.toString());
                }
            }else {
                //订单审核通过 财务未通过
                markMap.put("shipStatus", BasicConstant.ZERO.toString());
                markMap.put("expressStatus", BasicConstant.ZERO.toString());
                scheduleList.add(0,1);
                scheduleList.add(1,0);
                scheduleList.add(2,0);
                scheduleList.add(3,0);
                scheduleList.add(4,0);
            }
            stageLogListVO.setNowAndTotal(scheduleList);
            stageLogListVO.setScheduleMap(markMap);
            return stageLogListVO;
        }else {
            markMap.put("shipStatus", BasicConstant.ZERO.toString());
            markMap.put("expressStatus", BasicConstant.ZERO.toString());
            scheduleList.add(0);
            scheduleList.add(0);
            scheduleList.add(0);
            scheduleList.add(0);
            scheduleList.add(0);
            stageLogListVO.setNowAndTotal(scheduleList);
            stageLogListVO.setScheduleMap(markMap);
            return stageLogListVO;
        }
    }

    @Override
    public AfterSaveVO orderReview(OrderReviewDTO orderReviewDTO) throws XbbException {
        AfterSaveVO afterSaveVO = new AfterSaveVO();
        String corpid = orderReviewDTO.getCorpid();
        //当前用户权限
        Set<String> permSet = orderReviewDTO.getLoginUser().getPermSet();
        //数据ID
        Long dataId = orderReviewDTO.getDataId();
        //审核标示
        Integer review = orderReviewDTO.getReview();
        ContractEntityExt contractEntityExt = contractModel.getByKey(dataId, orderReviewDTO.getCorpid());
        JSONObject data = contractEntityExt.getData();
        String oldStatus = data.getString(OrderEnum.STATUS.getAttr());
        String status = null;
        //1 通过 2作废  校验是否有通过作废权限
        if (Objects.equals(review,BasicConstant.ONE)){
            if (!permSet.contains(ProPermissionAliasEnum.ORDER_THROUGH.getAlias())){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.ORDER_THROUGH.getMemo()));
            }
            // 收款状态
            Integer paymentStatus = FastJsonHelper.getIntegerOrDefaultFromFormData(data, OrderEnum.RECEIVE_PAYMENT_STATUS.getAttr(), BasicConstant.ONE);
            // 订单金额
            Double amount = FastJsonHelper.getDoubleOrDefaultFromFormData(data,OrderEnum.AMOUNT.getAttr(),0D);
            //根据收款状态 判断是否财务审核通过 更新订单状态
            if (Objects.equals(BasicConstant.ONE,paymentStatus) && !Objects.equals(amount,0D)){
                data.put(OrderEnum.STATUS.getAttr(),OrderStatusEnum.PENDING_FINANCIAL_REVIEW.getCode());
                status = OrderStatusEnum.PENDING_FINANCIAL_REVIEW.getCode();
            } else if (Objects.equals(BasicConstant.ONE,paymentStatus) && Objects.equals(amount,0D)){
                data.put(OrderEnum.STATUS.getAttr(),OrderStatusEnum.DELIVERED.getCode());
                data.put(OrderEnum.RECEIVE_PAYMENT_STATUS.getAttr(), OrderPayMentStatusEnum.RECEIPT_FUND.getCode());
                status = OrderStatusEnum.DELIVERED.getCode();
            } else {
                data.put(OrderEnum.STATUS.getAttr(),OrderStatusEnum.DELIVERED.getCode());
                status = OrderStatusEnum.DELIVERED.getCode();
            }
            contractEntityExt.setData(data);
        }else if (Objects.equals(review,BasicConstant.TWO)){
            if (!permSet.contains(ProPermissionAliasEnum.ORDER_CANCELLATION.getAlias())){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.ORDER_CANCELLATION.getMemo()));
            }
            String cancellMemo = orderReviewDTO.getMemo();

            String orderMemo= FastJsonHelper.getStringOrDefaultFromFormData(data, OrderEnum.MEMO.getAttr(), "");
            data.put(OrderEnum.MEMO.getAttr(), orderMemo + "\r\n" + "作废原因：" + cancellMemo);
            data.put(OrderEnum.STATUS.getAttr(),OrderStatusEnum.ABOLISHED.getCode());
            status = OrderStatusEnum.ABOLISHED.getCode();
            contractEntityExt.setData(data);
            //判断该订单下是否有回款单、发票，有则告知用户
            checkDownSheetInvoice(afterSaveVO, corpid, dataId, data);
            // 判断是否需要释放信用
            boolean checkUseCreditFlag = creditCardBillService.checkOrderCardBill(Arrays.asList(dataId), corpid);
            if (checkUseCreditFlag) {
                Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(data, OrderEnum.LINK_DISTRIBUTOR.getAttr(), 0L);
                String customerName = FastJsonHelper.getStringOrDefaultFromFormData(data, OrderEnum.LINK_CUSTOMER_HIDE.getAttr(), "");
                // 计算需要释放的剩余额度
                BigDecimal amount = creditCardBillService.calcCreditRemainLimit(customerId, dataId, corpid);
                CreditCardBillInfoPojo infoPojo = new CreditCardBillInfoPojo(CreditCardBillTypeEnum.ORDER_INVALID.getCode(), contractEntityExt.getId(), contractEntityExt.getSerialNo(), amount.doubleValue(), customerId, customerName, CreditCardBillTypeEnum.ORDER_INVALID.getXbbRefTypeEnum().getCode());
                infoPojo.setCreatorIsDistributor(BasicConstant.ZERO);
                CreditCardBillDTO creditCardBillDTO = new CreditCardBillDTO(Arrays.asList(infoPojo));
                BeanUtil.copyProperties(orderReviewDTO, creditCardBillDTO);
                saasCreditHelper.addBatchCreditCardBill(creditCardBillDTO);
            }
        }

        contractModel.update(contractEntityExt);
        writeOffRecordService.updateOrderStatus(status, dataId, corpid);
        String newStatus = status;
        // 消息异步处理
        Runnable runnable = () -> {
            //创建信息
            String creatorId = contractEntityExt.getCreatorId();
            Long contractId = contractEntityExt.getId();
            String type = data.getString(OrderEnum.TYPE.getAttr());
            int businessType = XbbRefTypeEnum.CONTRACT.getCode();
            try {
                List<String> pushDistributorUserList = new ArrayList<>();
                if (OrderTypeEnum.VALET_ORDER.getCode().equals(type)) {
                    pushDistributorUserList = pushHelper.getDistributorUserIdListByPushSetRule(corpid, contractEntityExt.getData().getLongValue(OrderEnum.LINK_DISTRIBUTOR.getAttr()));
                } else if (OrderTypeEnum.INDEPENDENT_ORDER.getCode().equals(type)) {
                    pushDistributorUserList = Collections.singletonList(data.getString(OrderEnum.ORDERER_ID.getAttr()));
                }
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(contractEntityExt.getAppId(), contractEntityExt.getMenuId(), contractEntityExt.getFormId(), contractId, Collections.singletonList(contractId), SaasMarkEnum.SAAS.getCode(), businessType, businessType);
                DistributorMessageRabbitMqDTO distributorMessageRabbitMqDTO;
                if (Objects.equals(review, BasicConstant.ONE)) {
                    // 审核通过
                    distributorMessageRabbitMqDTO = new DistributorMessageRabbitMqDTO(corpid, pushDistributorUserList, Collections.singletonList(contractId), 0, null, I18nMessageUtil.getMessage(DistributorOrderPushConstant.ORDER_REVIEW_TITLE), String.format(I18nMessageUtil.getMessage(DistributorOrderPushConstant.ORDER_REVIEW_CONTENT), contractEntityExt.getSerialNo()), null, options, DistributorMarkEnum.DISTRIBUTOR.getCode());
                    baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_ORDER_REVIEW_PUSH, distributorMessageRabbitMqDTO);
                } else if (Objects.equals(review, BasicConstant.TWO)) {
                    // 废弃
                    distributorMessageRabbitMqDTO = new DistributorMessageRabbitMqDTO(corpid, pushDistributorUserList, Collections.singletonList(contractId), 0, null, I18nMessageUtil.getMessage(DistributorOrderPushConstant.ORDER_ABANDONED_TITLE), String.format(I18nMessageUtil.getMessage(DistributorOrderPushConstant.ORDER_ABANDONED_CONTENT), contractEntityExt.getSerialNo()), null, options, DistributorMarkEnum.DISTRIBUTOR.getCode());
                    baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_ORDER_ABANDONED_PUSH, distributorMessageRabbitMqDTO);
                }

            } catch (Exception e) {
                LOG.error("订货单审核消息推送", e);
            }
            pushMessageChangeStatus(contractEntityExt, oldStatus, newStatus, corpid, orderReviewDTO);
        };
        threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
        return afterSaveVO;
    }

    @Override
    public ProductSummaryVO summaryProductList(BusinessProductListDTO businessProductListDTO) throws XbbException {
        // 获取参数
        String corpid = businessProductListDTO.getCorpid();
        Long dataId = businessProductListDTO.getDataId();
        String attr = businessProductListDTO.getAttr();
        PaasFormDataEntityExt contract = contractModel.getByKey(dataId, corpid);
        if (Objects.isNull(contract)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, corpid);
        modelMap.put(ParameterConstant.CONTRACT_ID, dataId);
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put("columns", "product_num, price,business_num,data");
        List<ContractProductEntity> contractProductEntities = contractProductModel.findEntitys(modelMap);

        ProductSummaryVO businessProductListVO = new ProductSummaryVO();
        PaasFormExplainEntity contractExplain = paasFormExplainModel.getByFormId(contract.getFormId(), businessProductListDTO.getCorpid());
        if (Objects.isNull(contractExplain)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(contractExplain.getExplains());
        // 关联产品字段
        FieldAttrEntity productField = explainMap.get(attr);
        // 产品合计
        FieldAttrEntity productTotalField = explainMap.get(ContractEnum.PRODUCT_TOTAL.getAttr());
        Double num = 0D;
        Double count = 0D;
        for (ContractProductEntity productEntity : contractProductEntities) {
            Double productNum = productEntity.getProductNum() != null ? productEntity.getProductNum(): 0D;
            Double price = productEntity.getPrice() == null ? 0D : productEntity.getPrice();
            double priceTotal = Objects.nonNull(productEntity.getData()) && Objects.nonNull(productEntity.getData().getDouble(ContractProductEnum.SUBTOTAL.getAttr())) ? productEntity.getData().getDouble(ContractProductEnum.SUBTOTAL.getAttr()) : Arith.mul(productNum, price);
            count = Arith.add(count, BigDecimal.valueOf(priceTotal).setScale(productTotalField.getAccuracy(), BigDecimal.ROUND_HALF_UP).doubleValue());
            num = Arith.add(num, productEntity.getBusinessNum() == null ? productNum : productEntity.getBusinessNum());
        }
        Boolean hidePrice = false;
        Integer productSize = contractProductEntities.size();
        String summaryInfo = String.format(I18nMessageUtil.getMessage(StringConstant.PRODUCTS_TYPE_NUM), productSize, Arith.doubleToBigDecimal(num));
        businessProductListVO.setSummaryInfo(summaryInfo);

        if (Objects.nonNull(productField)) {
            Map<Integer, List<UserTeamEntity>> userTeamMap = userTeamService.getUserTeam(dataId, corpid, XbbRefTypeEnum.CONTRACT.getCode());
            List<String> ownerIds = new ArrayList<>();
            List<String> coUserIds = new ArrayList<>();
            for (Map.Entry<Integer, List<UserTeamEntity>> entry : userTeamMap.entrySet()) {
                if (Objects.equals(entry.getKey(), BasicConstant.MAIN_USER)) {
                    entry.getValue().forEach(team -> ownerIds.add(team.getUserId()));
                } else if (Objects.equals(entry.getKey(), BasicConstant.COOP_USER)) {
                    entry.getValue().forEach(team -> coUserIds.add(team.getUserId()));
                }
            }
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            BeanUtil.copyProperties(businessProductListDTO, handlerExplainDTO);
            handlerExplainDTO.setOwnerId(ownerIds);
            handlerExplainDTO.setCoUserId(coUserIds);
            handlerExplainDTO.setCreatorId(contract.getCreatorId());
            SubFormPoJo subForm = productField.getSubForm();
            List<? extends FieldAttrEntity> fieldAttrEntityList = subForm.getItems();
            for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                if (Objects.equals(fieldAttrEntity.getAttr(), ContractProductEnum.SELLING_PRICE.getAttr())) {
                    if (ExplainUtil.isFieldNeedHide(fieldAttrEntity, handlerExplainDTO)) {
                        hidePrice = true;
                    }
                }
            }
        }

        businessProductListVO.setMoneyInfo(String.format(I18nMessageUtil.getMessage(StringConstant.PRODUCTS_MONEY_COUNT), I18nMessageUtil.getMessage(I18nStringConstant.SELL_PRICE), AttrDecimalPrecisionHelper.parseThousandth(count, productTotalField.getAccuracy())));
        if (hidePrice) {
            businessProductListVO.setMoneyInfo(String.format(I18nMessageUtil.getMessage(StringConstant.PRODUCTS_MONEY_COUNT), I18nMessageUtil.getMessage(I18nStringConstant.SELL_PRICE), StringConstant.INVISIBLE_VALUE));
        }
        JSONObject others = new JSONObject();
        others.put("hidePrice", hidePrice);
        others.put("amount", count);
        businessProductListVO.setOthers(others);
        Boolean isJxcUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
        if (isJxcUse) {
            //添加关闭的按钮,订货单没有开启按钮
            JSONObject data = contract.getData();
            String shipStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, OrderEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.UNSHIPPED.getCode());
            String orderStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, OrderEnum.STATUS.getAttr(), OrderStatusEnum.PENDING_ORDER_REVIEW.getCode());
            if (!Objects.equals(shipStatus, ShipStatusEnum.SHIPPED.getCode()) && num != 0D) {
                ButtonPojo buttonPojo = new ButtonPojo();
                if (!Objects.equals(shipStatus, ShipStatusEnum.CLOSED.getCode()) && businessProductListDTO.getLoginUser().getPermSet().contains(EnableButtonEnum.ORDER_UNABLE.getPermission()) && !Objects.equals(orderStatus, OrderStatusEnum.PENDING_ORDER_REVIEW.getCode()) && !Objects.equals(orderStatus, OrderStatusEnum.ABOLISHED.getCode())) {
                    buttonPojo.setAttr(XbbRefTypeEnum.CONTRACT.getAlias());
                    buttonPojo.setValue(OperateTypeEnum.UNABLE.getName());
                    buttonPojo.setLinkBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
                    List<ButtonPojo> topRightButton = new ArrayList<>();
                    topRightButton.add(buttonPojo);
                    businessProductListVO.setTopRightButton(topRightButton);
                }
            }
        }
        return businessProductListVO;
    }

    /**
     * 判断合同下面是否有回款单、销项发票，有的话并且合同有已收/已开票金额，则提示用户自己建红冲
     * @param afterSaveVO
     * @param corpid 公司id
     * @param dataId 合同id
     * @param data 合同data
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private void checkDownSheetInvoice(AfterSaveVO afterSaveVO, String corpid, Long dataId, JSONObject data) throws XbbException {
        //判断该订单下是否有回款单、发票，有则告知用户
        double finishAmount = data.getDoubleValue(OrderEnum.FINISH_AMOUNT.getAttr());
        double invoiceAmount = data.getDoubleValue(OrderEnum.INVOICE_AMOUNT.getAttr());
        //回款单
        BoolQueryBuilder sheetQueryBuilder = chartQueryHelp.boolQueryBuilder4Base(corpid);
        sheetQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));
        sheetQueryBuilder.filter(termQuery(PaymentSheetDistributorEnum.getEsAttr4Keyword(PaymentSheetDistributorEnum.ORDER), dataId));
        long countSheet = paasEsModel.count(sheetQueryBuilder, IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET);
        //销项发票
        BoolQueryBuilder invoiceQueryBuilder = chartQueryHelp.boolQueryBuilder4Base(corpid);
        invoiceQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));
        invoiceQueryBuilder.filter(termQuery(InvoiceDistributorEnum.getEsAttr4Keyword(InvoiceDistributorEnum.ORDER_ID), dataId));
        long countInvoice = paasEsModel.count(invoiceQueryBuilder, IndexTypeEnum.IDX_SAAS_INVOICE);
        StringBuilder stringBuilder = new StringBuilder();
        //订货单有已收金额，并且订货单有回款单 - 防止已经红冲完毕
        if(finishAmount > 0 && countSheet > 0){
            stringBuilder.append(XbbRefTypeEnum.PAYMENT_SHEET.getName());
        }
        //订货单有已开票金额，并且订货单有销项发票 - 防止已经红冲完毕
        if(invoiceAmount > 0 && countInvoice > 0){
            if (stringBuilder.length() > 0) {
                stringBuilder.append(SymbolConstant.COMMA_ENGLISH);
            }
            stringBuilder.append(XbbRefTypeEnum.INVOICE.getName());
        }
        if (stringBuilder.length() > 0) {
            JSONObject warningMsg = new JSONObject();
            warningMsg.put(BasicConstant.WARNING_MSG, String.format(I18nMessageUtil.getMessage(ErrorMessageConstant.ORDER_REVIEW_HAS_PAYMENT_SHEET_INVOICE), stringBuilder.toString()));
            afterSaveVO.setSpecialMsg(warningMsg);
        }
    }

    @Override
    public OrderDeleteBatchVO deleteBatch(OrderDeleteBatchDTO orderDeleteBatchDTO) throws XbbException {
        OrderDeleteBatchVO orderDeleteBatchVO = new OrderDeleteBatchVO();
        Integer businessType = orderDeleteBatchDTO.getBusinessType();
        XbbRefTypeEnum typeEnum = XbbRefTypeEnum.getByCode(businessType);
        // TODO 删除权限校验
        // TODO 如果该合同有回款单在审批中（待审批或审批中）则不让删除合同(批量时只要有一个有问题就返回错误)
        String corpid = orderDeleteBatchDTO.getCorpid();

        List<Long> deleteIdIn = orderDeleteBatchDTO.getDataIdList();
        if ( deleteIdIn.size() > BasicConstant.MAX_DEL_BATCH_COUNT ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100079.getCode(),String.format(SystemErrorCodeEnum.API_ERROR_100079.getMsg(), BasicConstant.MAX_DEL_BATCH_COUNT));
        }
        List<String> errorDataList = new ArrayList<>();
        Set<String> errorDataSet = new HashSet<>();
        Set<String> errorTypeSet = new HashSet<>();
        List<String> errorTypeList = new ArrayList<>();

        Map<String, String> noAndName= new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> paymentIdIn = new ArrayList<>();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(orderDeleteBatchDTO, true);
            param.put("idIn", deleteIdIn);
            param.put(ParameterConstant.COLUMNS, "id, serial_no, data");
            List<ContractEntityExt> contractList = contractModel.findEntitys(param);
            if (Objects.isNull(contractList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            // 兼容es有，数据库没有的情况
            List<Long> esIds = new ArrayList<>();
            if (!contractList.isEmpty()) {
                List<Long> dbId = new ArrayList<>();
                for (ContractEntityExt entityExt : contractList) {
                    dbId.add(entityExt.getId());
                }
                for (Long id : deleteIdIn) {
                    if (!dbId.contains(id)) {
                        esIds.add(id);
                    }
                }
            } else {
                esIds = deleteIdIn;
            }
            if (!esIds.isEmpty()) {
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                boolQueryBuilder.filter(termsQuery("dataId", esIds));
                List<String> fieldList = Arrays.asList("id", FieldTypeEnum.SERIALNO.getAlias(), ContractEnum.getAttrConnectData(ContractEnum.NAME));
                List<ContractEntityExt> esContracts = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTRACT, boolQueryBuilder, ContractEntityExt.class, fieldList);
                if (CollectionsUtil.isNotEmpty(esContracts)) {
                    contractList.addAll(esContracts);
                }
            }
            List<PaasProcessDataEntity> paymentSheetProcessList = paasProcessDataModel.getInApprovalDataByIdConditionJsonArray(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), PaymentSheetEnum.CONTRACT.getAttr(), deleteIdIn, corpid, Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(),FlowStatusEnum.IN_APPROVAL.getType()));
            if (Objects.isNull(paymentSheetProcessList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            //paymentSheetInApprove之前表示在审批阶段的回款单，现在表示只要存在审批中的回款单，或存在回款单就不能删除
            List<Long> paymentSheetInApprove = new ArrayList<>();
            paymentSheetProcessList.forEach(item->{
                JSONObject data = JSON.parseObject(item.getData());
                if (Objects.nonNull(data)) {
                    JSONArray contractIds = data.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
                    for (Object obj : contractIds) {
                        if ( Objects.nonNull(obj) ) {
                            Long contractId = StringUtil.StringToLong(obj.toString());
                            if(Objects.nonNull(contractId)) {
                                paymentSheetInApprove.add(contractId);
                            }
                        }
                    }
                }
            });

            List<Object> linkIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            deleteIdIn.forEach(id->{
                linkIdIn.add(id);
            });
            Map<Long, PaasFormDataEntityExt> paymentSheetEntityExtMap = paymentSheetService.getEsDataMapByLinkIds(corpid, linkIdIn, PaymentSheetEnum.CONTRACT);
            for (ContractEntityExt item:contractList) {
                Long contractId = item.getId();
                PaasFormDataEntityExt paymentSheetEntityExt = paymentSheetEntityExtMap.get(contractId);
                if ( Objects.nonNull(paymentSheetEntityExt) ){
                    paymentSheetInApprove.add(contractId);
                }
            }
            // 查询合同还有没有关联的退货退款单 youli.chen 未关联退货退款的正常删除

            Set<Long> linkRefundId = new HashSet<>();
            List<String> field = new ArrayList<>();
            List<PaasFormDataEntityExt> entityExts;
            // 查询合同还有没有关联的退货退款单 未关联退货退款的正常删除
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder queryBuilder = boolQuery();
            queryBuilder.filter(termQuery("corpid.keyword", corpid));
            queryBuilder.filter(termsQuery("data." + RefundEnum.CONTRACT_ID.getAttr(), deleteIdIn));
            queryBuilder.filter(termQuery("del", 0));
            // 设置join_field
            queryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_REFUND.getType()));
            sourceBuilder.query(queryBuilder);
            field.add(RefundEnum.CONTRACT_ID.getAttr());
            entityExts = paasEsModel.list(sourceBuilder, IndexTypeEnum.IDX_SAAS_REFUND, field, null, null);
            if (Objects.nonNull(entityExts)) {
                for (PaasFormDataEntityExt entity : entityExts) {
                    JSONObject data = entity.getData();
                    Long contractId = data.getLong(RefundEnum.CONTRACT_ID.getAttr());
                    linkRefundId.add(contractId);
                }
            }

            // 获取销项发票是否在审批中
            List<PaasProcessDataEntity> invoiceProcessList = paasProcessDataModel.getInvoiceInApprovalDataByIdConditionJsonArray(XbbRefTypeEnum.INVOICE.getCode(), PaymentSheetEnum.CONTRACT.getAttr(), deleteIdIn, corpid, Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(),FlowStatusEnum.IN_APPROVAL.getType()));
            //paymentSheetInApprove之前表示在审批阶段的回款单，现在表示只要存在审批中的回款单，或存在回款单就不能删除
            List<Long> invoiceInApprove = new ArrayList<>();
            invoiceProcessList.forEach(item->{
                JSONObject data = JSON.parseObject(item.getData());
                if (Objects.nonNull(data)) {
                    JSONArray contractIds = data.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
                    for (Object obj : contractIds) {
                        Long contractId = StringUtil.StringToLong((String) obj);
                        if(Objects.nonNull(contractId)) {
                            invoiceInApprove.add(contractId);
                        }
                    }
                }
            });

            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("contractIdIn",deleteIdIn);
            map.put("corpid",corpid);
            map.put("del",DelEnum.NORMAL);
            List<InvoiceRelationshipEntity> invoiceRelationshipEntityList = invoiceRelationshipModel.findEntitys(map);
            Set<Long> invoiceRelationshipContractList = new HashSet<>();
            Map<Long,Long> contractRefInvoiceId = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            invoiceRelationshipEntityList.forEach(invoiceRelationshipEntity -> {
                invoiceRelationshipContractList.add(invoiceRelationshipEntity.getContractId());
                contractRefInvoiceId.put(invoiceRelationshipEntity.getContractId(),invoiceRelationshipEntity.getInvoiceId());
            });


            List<Long> physicalDelIds = new ArrayList<>();
            physicalDelIds.addAll(deleteIdIn);
            // 查询合同是否有下游单据销售出库单，生成了关联销售出库单的不允许删除
            Set<Long> linkOutstackId = new HashSet<>();
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termsQuery("data." + OutstockEnum.REF_ID.getAttr(), deleteIdIn));
            boolQueryBuilder.filter(termQuery("data." + OutstockEnum.TYPE.getAttr(), OutstockTypeEnum.CONTRACT_OUTSTOCK.getCode()));
            boolQueryBuilder.filter(termQuery("del", 0));
            // 设置join_field
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_CONTRACT_OUTSTOCK.getType()));
            sourceBuilder.query(boolQueryBuilder);
            field.clear();
            field.add(OutstockEnum.REF_ID.getAttr());
            entityExts = paasEsModel.list(sourceBuilder, IndexTypeEnum.IDX_SAAS_CONTRACT_OUTSTOCK, field, null, null);

            if (Objects.nonNull(entityExts)) {
                for (PaasFormDataEntityExt entity : entityExts) {
                    JSONObject data = entity.getData();
                    Long contractId = data.getLong(OutstockEnum.REF_ID.getAttr());
                    linkOutstackId.add(contractId);
                }
            }
            for (ContractEntityExt item: contractList) {
                String no = item.getSerialNo();
                String name = FastJsonHelper.getStringOrDefaultFromFormData(item.getData(), ContractEnum.NAME.getAttr(), "");
                noAndName.put(no, name);
            }
            // 未关联退货退款的合同ID
            deleteIdIn.removeAll(linkRefundId);
            deleteIdIn.removeAll(linkOutstackId);
            for(ContractEntityExt item: contractList){
                JSONObject contractObj = item.getData();
                if(linkRefundId.contains(item.getId())){
                    errorTypeSet.add(String.format(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_RETURN_NOT_DEL), typeEnum.getName()));
                    errorDataSet.add(item.getSerialNo());
                }
                // 合同关联销售出库单，不允许删除
                if (linkOutstackId.contains(item.getId())) {
                    errorTypeSet.add(String.format(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_ORDER_OUTSTOCK_NOT_DEL), typeEnum.getName()));
                    errorDataSet.add(item.getSerialNo());
                }
                // 回款单存在审批中的，不允许删除
                if(paymentSheetInApprove.contains(item.getId())) {
                    deleteIdIn.remove(item.getId());
                    errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_PAYMENT_SHEET_NOT_DEL));
                    errorDataSet.add(item.getSerialNo());
                }

                if(invoiceInApprove.contains(item.getId())){
                    deleteIdIn.remove(item.getId());
                    errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_INVOICE_APPROVE_NOT_DEL));
                    errorDataSet.add(item.getSerialNo());
                }
                if(invoiceRelationshipContractList.contains(item.getId())){
                    //Long invoiceId = contractRefInvoiceId.getOrDefault(item.getId(),0L);
                    deleteIdIn.remove(item.getId());
                    errorTypeSet.add(String.format(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_CONTRACT_INVOICE_NOT_DEL), typeEnum.getName()));
                    errorDataSet.add(item.getSerialNo());
                }
                // 收款状态不为待结算，不能删除
                if (!Objects.equals(item.getData().getString(OrderEnum.RECEIVE_PAYMENT_STATUS.getAttr()), OrderPayMentStatusEnum.PENDING_SETTLEMENT.getCode())) {
                    deleteIdIn.remove(item.getId());
                    errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.HAVE_ORDER_PAYMENT_NOT_DEL));
                    errorDataSet.add(item.getSerialNo());
                }
            }
            errorDataList.addAll(errorDataSet);
            errorTypeList.addAll(errorTypeSet);
            if (!deleteIdIn.isEmpty()) {
                orderDeleteBatchVO.setDeleteIds(deleteIdIn);
                if(BasicConstant.ONE.equals(orderDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(deleteIdIn.size())){
                    contractModel.deleteByKey(deleteIdIn.get(0),corpid);
                }else {
                    contractModel.deleteBatch(deleteIdIn, corpid);
                }
                // 删除合同联系人
                ContractUserDeleteBatchDTO contractUserDeleteBatchDTO = new ContractUserDeleteBatchDTO();
                BeanUtil.copyProperties(orderDeleteBatchDTO, contractUserDeleteBatchDTO);
                contractUserDeleteBatchDTO.setContractIdIn(deleteIdIn);
                contractUserService.deleteBatch(contractUserDeleteBatchDTO);
            }

            // 删除相关回款计划
            if (!deleteIdIn.isEmpty()) {
                BoolQueryBuilder booleanQuery = boolQuery();
                booleanQuery.filter(termsQuery(StringConstant.JSON_DATA +StringConstant.POINT + PaymentEnum.CONTRACT.getAttr(), deleteIdIn));
                booleanQuery.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
                booleanQuery.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
                List<String> fieldList = new ArrayList<>();
                fieldList.add(FieldTypeEnum.DATAID.getAlias());
                List<PaasFormDataEntityExt> paymentList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PAYMENT, booleanQuery, PaasFormDataEntityExt.class, fieldList);
                if (Objects.isNull(paymentList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                }
                paymentList.forEach((item)->{
                    paymentIdIn.add(item.getDataId());
                });
                if (!paymentIdIn.isEmpty()) {
                    PaymentDeleteBatchDTO paymentDeleteBatchDTO = new PaymentDeleteBatchDTO();
                    BeanUtil.copyProperties(orderDeleteBatchDTO, paymentDeleteBatchDTO, true);
                    paymentDeleteBatchDTO.setDataIdList(paymentIdIn);
                    paymentService.deleteBatch(paymentDeleteBatchDTO);
                }
                // 删除合同业绩分配
                ContractPerformanceDeleteBatchDTO contractPerformanceDeleteBatchDTO = new ContractPerformanceDeleteBatchDTO();
                BeanUtil.copyProperties(orderDeleteBatchDTO, contractPerformanceDeleteBatchDTO, true);
                contractPerformanceDeleteBatchDTO.setContractIdIn(deleteIdIn);
                contractPerformanceService.deleteBatch(contractPerformanceDeleteBatchDTO);
                // 删除合同产品
                ContractProductDeleteBatchDTO contractProductDeleteBatchDTO = new ContractProductDeleteBatchDTO();
                BeanUtil.copyProperties(orderDeleteBatchDTO, contractProductDeleteBatchDTO, true);
                contractProductDeleteBatchDTO.setContractIdIn(deleteIdIn);
                contractProductService.deleteBatch(contractProductDeleteBatchDTO);
                // 删除合同的其他费用
                ContractSurchargeDeteleBatchDTO contractSurchargeDeteleBatchDTO = new ContractSurchargeDeteleBatchDTO();
                BeanUtil.copyProperties(orderDeleteBatchDTO, contractSurchargeDeteleBatchDTO, true);
                contractSurchargeDeteleBatchDTO.setContractIdIn(deleteIdIn);
                contractSurchargeService.deleteBatchByContractId(contractSurchargeDeteleBatchDTO);
                PushNotifyDeleteDTO pushNotifyDeleteDTO = new PushNotifyDeleteDTO();
                BeanUtil.copyProperties(orderDeleteBatchDTO, pushNotifyDeleteDTO);
                pushNotifyDeleteDTO.setNeedDelNotifyIdList(deleteIdIn);
                pushNotifyDeleteDTO.setBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
                pushNotifyService.deletePushNotify(pushNotifyDeleteDTO);
            }

            // TODO 删除相关审批记录

            // 动态: 经销商，暂不考虑
            // DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategy(ProjectLogEnum.ORDER_DELETE.getSubType());
            // FormDataDeleteBatchDTO formDataDeleteBatchDTO = BeanUtil.copyProperties(orderDeleteBatchDTO, FormDataDeleteBatchDTO.class, true);
            // List<PaasFormDataEntityExt> allowDeletePaasFormDatas = new ArrayList<>(contractList.size());
            // BeanUtil.copyPropertiesList(contractList, allowDeletePaasFormDatas, PaasFormDataEntityExt.class);
            // dynamicStrategy.batchDelete(DynamicDeleteDTO.initDynamicDeleteDTO(formDataDeleteBatchDTO, deleteIdIn, allowDeletePaasFormDatas));

            //生成删除日志(区分单个删除和批量删除)
            String userId = orderDeleteBatchDTO.getUserId();
            String userName = orderDeleteBatchDTO.getLoginUserName();
            List<String> list = new ArrayList<>();
            Iterator<String> iterator = noAndName.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                String value = noAndName.get(key);
                if(StringUtil.isEmpty(value)){
                    list.add(key);
                } else {
                    StringBuilder sb = new StringBuilder();
                    sb.append(key).append("（").append(value).append("）");
                    list.add(sb.toString());
                }
            }
            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            if (Objects.equals(1, orderDeleteBatchDTO.getIsBusinessRule())) {
                operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            }
            String nameStr = StringUtils.join(list, "，");
            if(deleteIdIn.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.CONTRACT.getName(), deleteIdIn.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(ContractEnum.CONTRACT_NO.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.CONTRACT, operateTypeEnum,
                        "", "", memo, orderDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(deleteIdIn.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.CONTRACT.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.CONTRACT, operateTypeEnum,
                        deleteIdIn.get(0).toString(), nameStr, memo, orderDeleteBatchDTO.getHttpHeader());
            }

        } catch (Exception e) {
            contractService.updateRollback(orderDeleteBatchDTO.getDataIdList(), corpid);
            paymentService.updateRollback(paymentIdIn, corpid);
            contractPerformanceService.updateRollbackByContractId(orderDeleteBatchDTO.getDataIdList(), corpid);
            contractUserService.updateRollbackByContractId(orderDeleteBatchDTO.getDataIdList(), corpid);
            contractProductService.updateRollbackByContractId(orderDeleteBatchDTO.getDataIdList(), corpid);
            LOG.error("contractServiceImpl.deleteBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        orderDeleteBatchVO.setErrorDataList(errorDataList);
        orderDeleteBatchVO.setErrorTypeList(errorTypeList);
        orderDeleteBatchVO.setErrorDataMemo(SaasDeleteHelp.getErrorDataMemo(errorTypeList, errorDataList));
        return orderDeleteBatchVO;
    }

    public void pushMessageChangeStatus(ContractEntityExt contractEntityExt,String oldStatus, String newStatus, String corpid, BaseDTO baseDTO) {
        try {
            // 订单状态变更消息推送
            Long contractId = contractEntityExt.getDataId();
            Integer pushType = XbbRefTypeEnum.CONTRACT.getCode();
            oldStatus = OrderStatusEnum.getByCode(oldStatus).getName();
            newStatus = OrderStatusEnum.getByCode(newStatus).getName();
            List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.ORDER_CHANGE_PUSH.getCode(), PushTypeEnum.ORDER_CHANGE_PUSH.getSubCode(), baseDTO.getLoginUser(), contractEntityExt);
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(contractEntityExt.getAppId(), contractEntityExt.getMenuId(), contractEntityExt.getFormId(), contractId, Collections.singletonList(contractId), SaasMarkEnum.SAAS.getCode(), pushType, pushType);
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(contractId), 0, null, I18nMessageUtil.getMessage(OrderPushConstant.ORDER_CHANGE_TITLE), String.format(I18nMessageUtil.getMessage(OrderPushConstant.ORDER_CHANGE_CONTENT), baseDTO.getLoginUserName(), oldStatus, newStatus), null, options);
            baseProducer.sendMessage(PushTypeEnum.ORDER_CHANGE_PUSH, messageRabbitMqDTO);
        } catch (Exception e) {
            LOG.error("订货单保存时订单状态变更消息推送", e);
        }
    }
}
